package com.yipei.business.service.impl;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yipei.business.domain.MlAccountMessage;
import com.yipei.business.domain.MlTradeEntrustOrder;
import com.yipei.business.service.IMlAssetFlowService;
import com.yipei.business.service.IMlTradeEntrustOrderService;
import com.yipei.common.constant.HttpStatus;
import com.yipei.common.constant.LoginPasswordParam;
import com.yipei.common.exception.ServiceException;
import com.yipei.common.exception.user.UserNotExistsException;
import com.yipei.common.utils.DateUtils;
import com.yipei.common.utils.MessageUtils;
import com.yipei.common.utils.SecurityUtils;
import com.yipei.common.utils.StringUtils;
import com.yipei.common.utils.uuid.IdUtils;
import com.yipei.common.utils.uuid.UUID;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yipei.business.mapper.MlTradeAccountMapper;
import com.yipei.common.core.domain.entity.MlTradeAccount;
import com.yipei.business.service.IMlTradeAccountService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

/**
 * 交易账号Service业务层处理
 *
 * @author yipei
 * @date 2024-12-21
 */
@Service
public class MlTradeAccountServiceImpl extends ServiceImpl<MlTradeAccountMapper,MlTradeAccount> implements IMlTradeAccountService
{
    @Autowired
    private MlTradeAccountMapper mlTradeAccountMapper;
    @Autowired
    private MlAccountMessageServiceImpl mlAccountMessageService;
    @Autowired
    private IMlTradeEntrustOrderService iMlTradeEntrustOrderService;

    @Autowired
    private IMlAssetFlowService iMlAssetFlowService;

    /**
     * 查询交易账号
     *
     * @param id 交易账号主键
     * @return 交易账号
     */
    @Override
    public MlTradeAccount selectMlTradeAccountById(Long id)
    {
        return mlTradeAccountMapper.selectMlTradeAccountById(id);
    }

    /**
     * 查询交易账号列表
     *
     * @param mlTradeAccount 交易账号
     * @return 交易账号
     */
    @Override
    public List<MlTradeAccount> selectMlTradeAccountList(MlTradeAccount mlTradeAccount)
    {
        return mlTradeAccountMapper.selectMlTradeAccountList(mlTradeAccount);
    }

    /**
     * 新增交易账号
     *
     * @param mlTradeAccount 交易账号
     * @return 结果
     */
    @Override
    public int insertMlTradeAccount(MlTradeAccount mlTradeAccount)
    {
        mlTradeAccount.setCreateTime(DateUtils.getNowDate());
        mlTradeAccount.setTdPwd(SecurityUtils.encryptPassword(mlTradeAccount.getTdPwd()));
        mlTradeAccount.setTdAcc(generate());
        mlTradeAccount.setAtAcc(generate2());
        mlTradeAccount.setDjCash(BigDecimal.ZERO);
        mlTradeAccount.setCash(BigDecimal.ZERO);
        mlTradeAccount.setKqZj(BigDecimal.ZERO);
        mlTradeAccount.setAaLock(BigDecimal.ZERO);
        MlAccountMessage mlAccountMessage=new MlAccountMessage();
        mlAccountMessage.setContent("您的交易账号已经开通:<div>账号:"+ mlTradeAccount.getTdAcc()+"</div><div>类型: "+mlTradeAccount.getTdType()+"</div>");
        mlAccountMessage.setTdAcc(mlTradeAccount.getTdAcc());
        mlAccountMessage.setXxLx(BigDecimal.ZERO);
        mlAccountMessage.setTitle("账号已开通提示");
        mlAccountMessageService.insertMlAccountMessage(mlAccountMessage);
        return mlTradeAccountMapper.insertMlTradeAccount(mlTradeAccount);
    }
    public static String generate() {
        long time = System.currentTimeMillis() % 1000000; // 取后6位
        int rand = (int) (Math.random() * 1000); // 3位随机
        return String.format("%06d%03d", time, rand);
    }

    public static String generate2() {
        String uuid = UUID.randomUUID().toString().replace("-", "");
        long num = Math.abs(uuid.hashCode());
        String numStr = String.format("%010d", num);
        // 取前10位
        return numStr.substring(0, 10);
    }
    /**
     * 修改交易账号
     *
     * @param mlTradeAccount 交易账号
     * @return 结果
     */
    @Override
    @Transactional
    public int updateMlTradeAccount(MlTradeAccount mlTradeAccount)
    {
        if (StringUtils.isNotEmpty(mlTradeAccount.getTdPwd())){
            mlTradeAccount.setTdPwd(SecurityUtils.encryptPassword(mlTradeAccount.getTdPwd()));
        }else {
            MlTradeAccount one = lambdaQuery().eq(MlTradeAccount::getTdAcc, mlTradeAccount.getTdAcc()).one();
            mlTradeAccount.setTdPwd(one.getTdPwd());
        }

        MlTradeAccount one = lambdaQuery().eq(MlTradeAccount::getTdAcc, mlTradeAccount.getTdAcc()).one();
        /**
         * 可取资金大于数据库可取资金，资金流水+可取资金，小于数据库就是，资金流水-可取资金
         */
        if ((one.getKqZj().compareTo(mlTradeAccount.getKqZj())!=0)){
            BigDecimal subtract = mlTradeAccount.getKqZj().subtract(one.getKqZj());
            iMlAssetFlowService.creatObject(one.getTdAcc(),5,subtract);
            mlTradeAccount.setCash((mlTradeAccount.getCash()==null?BigDecimal.ZERO:mlTradeAccount.getCash()).add(subtract));
        }
        mlTradeAccount.setUpdateTime(DateUtils.getNowDate());
        return mlTradeAccountMapper.updateMlTradeAccount(mlTradeAccount);
    }

    /**
     * 批量删除交易账号
     *
     * @param ids 需要删除的交易账号主键
     * @return 结果
     */
    @Override
    public int deleteMlTradeAccountByIds(Long[] ids)
    {
        return mlTradeAccountMapper.deleteMlTradeAccountByIds(ids);
    }

    /**
     * 删除交易账号信息
     *
     * @param id 交易账号主键
     * @return 结果
     */
    @Override
    public int deleteMlTradeAccountById(Long id)
    {
        return mlTradeAccountMapper.deleteMlTradeAccountById(id);
    }

    @Override
    public void updateLoginPassword(LoginPasswordParam loginPasswordParam) {
        if (StringUtils.isEmpty(loginPasswordParam.getOldPassword()) || StringUtils.isEmpty(loginPasswordParam.getNewPassword1()) ||
                StringUtils.isEmpty(loginPasswordParam.getNewPassword2())) {
            throw new ServiceException(MessageUtils.message("params.error"), HttpStatus.ERROR);
        }
        MlTradeAccount mlTradeAccount = this.getById(loginPasswordParam.getUserId());
        // 用户不存在
        if (ObjectUtils.isEmpty(mlTradeAccount)) {
            throw new UserNotExistsException();
        }

        if (!loginPasswordParam.getNewPassword1().equals(loginPasswordParam.getNewPassword2())) {
            throw new ServiceException(MessageUtils.message("重复密码不一致"), HttpStatus.ERROR);
        }
//        if (!SecurityUtils.matchesPassword(loginPasswordParam.getOldPwd(), mlTradeAccount.getTdPwd())) {
//            throw new ServiceException(MessageUtils.message("旧密码错误"), HttpStatus.ERROR);
//        }

        LambdaUpdateWrapper<MlTradeAccount> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(MlTradeAccount::getId, mlTradeAccount.getId());
        lambdaUpdateWrapper.set(MlTradeAccount::getTdPwd, SecurityUtils.encryptPassword(loginPasswordParam.getNewPassword1()));
        lambdaUpdateWrapper.set(MlTradeAccount::getUpdateTime, new Date());
        this.update(lambdaUpdateWrapper);

    }

    @Override
    public void djCashByKqZjJob() {
        LambdaUpdateWrapper<MlTradeAccount> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.gt(MlTradeAccount::getDjCash,0).eq(MlTradeAccount::getTdAcc,"191746880");
        List<MlTradeAccount> list = this.list(lambdaUpdateWrapper);
        if (!CollectionUtils.isEmpty(list)){
            for (MlTradeAccount mlTradeAccount : list) {
                mlTradeAccount.setKqZj(mlTradeAccount.getKqZj().add(mlTradeAccount.getDjCash()));
                mlTradeAccount.setCash(mlTradeAccount.getCash().add(mlTradeAccount.getDjCash()));
                mlTradeAccount.setDjCash(BigDecimal.ZERO);
            }
        }
        this.updateBatchById(list,100);
    }
    @Transactional
    @Override
    public MlTradeAccount register(MlTradeAccount mlTradeAccount) {
        if (StringUtils.isEmpty(mlTradeAccount.getAtAcc()) || StringUtils.isEmpty(mlTradeAccount.getTdPwd())
                || StringUtils.isEmpty(mlTradeAccount.getConfirmPassword())
        ) {
            throw new ServiceException(MessageUtils.message("参数错误"), HttpStatus.ERROR);
        }
        // 两次密码校验
        if (!mlTradeAccount.getTdPwd().equals(mlTradeAccount.getConfirmPassword())) {
            throw new ServiceException(MessageUtils.message("两次密码不一致"), HttpStatus.ERROR);
        }
        mlTradeAccount.setTdAcc(mlTradeAccount.getAtAcc());
        // 手机号校验
        this.checkMobile(mlTradeAccount.getAtAcc());
        // 保存用户信息
        mlTradeAccount.setTdPwd(SecurityUtils.encryptPassword(mlTradeAccount.getTdPwd()));
        mlTradeAccount.setCreateTime(new Date());
        mlTradeAccount.setDjCash(BigDecimal.ZERO);
        mlTradeAccount.setTdType(new BigDecimal(2));
        mlTradeAccount.setFFive(BigDecimal.ONE);
        mlTradeAccount.setStatus(1l);
        mlTradeAccount.setCash(BigDecimal.ZERO);
        mlTradeAccount.setBuyRate(new BigDecimal("0.001"));
        mlTradeAccount.setSellRate(new BigDecimal("0.001"));
        MlAccountMessage mlAccountMessage=new MlAccountMessage();
        mlAccountMessage.setContent("您的交易账号已经开通:<div>账号:"+ mlTradeAccount.getTdAcc()+"</div><div>类型: "+mlTradeAccount.getTdType()+"</div>");
        mlAccountMessage.setTdAcc(mlTradeAccount.getTdAcc());
        mlAccountMessage.setXxLx(BigDecimal.ZERO);
        mlAccountMessage.setTitle("账号已开通提示");
        mlAccountMessageService.insertMlAccountMessage(mlAccountMessage);
        this.save(mlTradeAccount);
        mlTradeAccount = this.getById(mlTradeAccount.getId());
        return mlTradeAccount;
    }

    @Override
    public List<MlTradeEntrustOrder> getMlTradeEntrustOrder(String tdAcc) {
        return iMlTradeEntrustOrderService.lambdaQuery().eq(MlTradeEntrustOrder::getTdAcc,tdAcc).in(MlTradeEntrustOrder::getWtZt,"0","1").list();
    }

    @Override
    public Map<String, MlTradeAccount> getAccountMapByTdAccs(Set<String> tdAccSet) {
        if (tdAccSet == null || tdAccSet.isEmpty()) {
            return Collections.emptyMap();
        }
        // 一次性查出所有账户
        List<MlTradeAccount> accountList = this.list(
                new LambdaQueryWrapper<MlTradeAccount>().in(MlTradeAccount::getTdAcc, tdAccSet)
        );
        // 转为Map，key=tdAcc
        return accountList.stream().collect(Collectors.toMap(MlTradeAccount::getTdAcc, a -> a));
    }

    private void checkMobile(String atAcc) {
        LambdaQueryWrapper<MlTradeAccount> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(MlTradeAccount::getAtAcc, atAcc);
        lambdaQueryWrapper.last(" limit 1 ");
        MlTradeAccount mlTradeAccount = this.getOne(lambdaQueryWrapper);
        if (ObjectUtils.isNotEmpty(mlTradeAccount)) {
            throw new ServiceException(MessageUtils.message("手机号不能重复注册"), HttpStatus.ERROR);
        }
    }

//    @Override
//    public void recordLoginInfo(MlTradeAccount mlTradeAccount) {
//        LambdaUpdateWrapper<MlTradeAccount> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
//        lambdaUpdateWrapper.eq(MlTradeAccount::getId, mlTradeAccount.getId());
//
//        // 连续登录天数
//        int successions = mlTradeAccount.getSuccessions();
//        // 最大连续登录天数
//        int maxSuccessions = mlTradeAccount.getMaxSuccessions();
//        // 计算是否超出48小时，否则连续登录天数加1
//        long now = new Date().getTime();
//        if (null == mlTradeAccount.getLoginTime()) {
//            mlTradeAccount.setLoginTime(new Date());
//        }
//        long old = mlTradeAccount.getLoginTime().getTime();
//        long betweenDays = (now - old) / 24 / 60 / 60 / 1000;
//        if (betweenDays < 2) {
//            successions++;
//            lambdaUpdateWrapper.set(FaMember::getSuccessions, successions);
//            if (successions > maxSuccessions) {
//                maxSuccessions = successions;
//                lambdaUpdateWrapper.set(FaMember::getMaxSuccessions, maxSuccessions);
//            }
//        } else {
//            successions = 1;
//            lambdaUpdateWrapper.set(FaMember::getSuccessions, successions);
//        }
//        lambdaUpdateWrapper.set(FaMember::getPrevTime, mlTradeAccount.getLoginTime());
//        lambdaUpdateWrapper.set(FaMember::getLoginTime, new Date());
//        lambdaUpdateWrapper.set(FaMember::getLoginIp, IpUtils.getIpAddr());
//        this.update(lambdaUpdateWrapper);
//    }
}
